package com.jie.state;

import com.jie.entity.Article;
import com.jie.enums.ArticleFlowEvent;
import com.jie.enums.ArticleFlowStateEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.persist.StateMachinePersister;
import org.springframework.statemachine.support.DefaultStateMachineContext;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * @Author: 杰
 * @Project :net-disk
 * @DateTime: 2024/5/30 16:57
 **/
@Service
@Slf4j
public class ArticleStateServiceImpl {
    @Resource
    private StateMachine<ArticleFlowStateEnum, ArticleFlowEvent> stateMachine;
    @Resource
    private StateMachinePersister<ArticleFlowStateEnum, ArticleFlowEvent, String> stateMachineRedisPersister;

    public synchronized boolean sendEvent(ArticleFlowEvent articleFlowEvent, Article article, String key) {
        log.info("准备发送事件: " + article);
        boolean result = false;
        String stateKey="articleState:"+article.getId();
        try {
            // 启动状态机
            stateMachine.start();
            //从redis回复之前状态机状态
            stateMachineRedisPersister.restore(stateMachine, stateKey);
            // 构建事件消息
            Message<ArticleFlowEvent> message = MessageBuilder.withPayload(articleFlowEvent).setHeader("article", article).build();
            log.info("发送事件: " + article);
            // 发送事件
            result = stateMachine.sendEvent(message);
            if (!result) {
                return false;
            }
            Integer o = (Integer) stateMachine.getExtendedState().getVariables().get(key + article.getId());
            // 等待状态转换完成（根据需要添加监听器来获取状态转换结果）
            stateMachine.getExtendedState().getVariables().remove(key + article.getId());
            if (Objects.equals(1, o)) {
                //redis持久化状态机状态
                stateMachineRedisPersister.persist(stateMachine, stateKey);
            }
        } catch (Exception e) {
            log.error("发送事件时出错", e);
        } finally {
            stateMachine.stop();
        }
        return result;
    }
}
